﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Red.Controls.Shell;

namespace Red.Launcher.ActiveDirectory
{
    public partial class Import : RedWindow
    {
        #region Private Data

        private string _cachedSearchLowerCase;
        private bool _filterEmpty;
        private bool _filterEmptyNames;
        private bool _filterExpired;
        private bool _filterStale;
        private bool _filterExisting;

        #endregion Private Data

        #region Dependency Properties

        public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register( "IsBusy", typeof( bool ), typeof( Import ) );

        #endregion Dependency Properties

        #region Public Properties

        public bool IsBusy
        {
            get { return (bool)GetValue( IsBusyProperty ); }
            private set { SetValue( IsBusyProperty, value ); }
        }

        public Users Users { get; private set; } = new Users();

        public bool FilterEmpty
        {
            get { return _filterEmpty; }
            set
            {
                if( _filterEmpty != value )
                {
                    _filterEmpty = value;
                    UpdateFilter();
                }
            }
        }
        public bool FilterEmptyNames
        {
            get { return _filterEmptyNames; }
            set
            {
                if ( _filterEmptyNames != value )
                {
                    _filterEmptyNames = value;
                    UpdateFilter();
                }
            }
        }

        public bool FilterExpired
        {
            get { return _filterExpired; }
            set
            {
                if ( _filterExpired != value )
                {
                    _filterExpired = value;
                    UpdateFilter();
                }
            }
        }

        public bool FilterStale
        {
            get { return _filterStale; }
            set
            {
                if ( _filterStale != value )
                {
                    _filterStale = value;
                    UpdateFilter();
                }
            }
        }

        public bool FilterExisting
        {
            get { return _filterExisting; }
            set
            {
                if ( _filterExisting != value )
                {
                    _filterExisting = value;
                    UpdateFilter();
                }
            }
        }

        #endregion Public PRoperties

        #region C-Tor

        public Import()
        {
            InitializeComponent();

            Users.View.Filter = new Predicate<object>( FilterInternal );

            _refresh.Click += _refresh_Click;
            _search.TextChanged += _search_TextChanged;
        }

        #endregion C-Tor

        #region Private Methods

        private void UpdateFilter()
        {
            Users.View.Refresh();
        }

        #endregion Private Methods

        #region Event Handlers

        private bool FilterInternal( object obj )
        {
            Users.User user = (Users.User)obj;

            if ( FilterEmpty && string.IsNullOrWhiteSpace( user.Principal.UserPrincipalName ) )
                return false;

            if ( FilterEmptyNames && string.IsNullOrWhiteSpace( user.Principal.DisplayName ) )
                return false;

            if ( FilterExpired && user.Principal.AccountExpirationDate < DateTime.Now )
                return false;

            if ( FilterStale && user.Principal.LastLogon < ( DateTime.Now - TimeSpan.FromDays( 30 ) ) )
                return false;

            if ( FilterExisting && user.ExistsInDatabase )
                return false;

            if ( !string.IsNullOrWhiteSpace( _cachedSearchLowerCase ) && !( user.Principal.DisplayName?.ToLower().Contains( _cachedSearchLowerCase ) == true || user.Principal.SamAccountName.Contains( _cachedSearchLowerCase ) ) )
                return false;

            return true;
        }

        private async void _refresh_Click( object sender, RoutedEventArgs e )
        {
            IsBusy = true;
            Users.Clear();

            await Users.Fetch();
            IsBusy = false;
        }

        private void Cancel_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            Close();
        }

        private async void Ok_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            IsBusy = true;

            if ( await Users.Import() )
            {
                Close();
            }
            else
            {
                RedMessageBox.Show( this, RedDialogType.Ok, "There was a problem adding users to the database", mode: RedMessageBox.Mode.Warning );
            }

            IsBusy = false;
        }

        private void Ok_CanExecute( object sender, CanExecuteRoutedEventArgs e )
        {
            e.CanExecute = !IsBusy;
        }

        private void _search_TextChanged( object sender, TextChangedEventArgs e )
        {
            _cachedSearchLowerCase = _search.Text.ToLower();

            UpdateFilter();
        }

        #endregion Event Handlers
    }
}
